<template>
    <div class="product-edit">
        <el-card class="box-card">
            <template v-slot:header>
<div  class="clearfix">
                <span>{{ isEdit ? '商品编辑' : '商品上架' }}</span>
            </div>
</template>
            <!-- 表单 -->
            <el-form :model="form" :rules="rules" ref="formRef" label-width="120px" :disabled="submitLoading">
                <!-- 基本信息 -->
                <el-divider content-position="left">基本信息</el-divider>
                <el-form-item label="商品名称" prop="title">
                    <el-input v-model="form.title" placeholder="请输入商品名称" max-length="100"></el-input>
                </el-form-item>
                <el-form-item label="副标题" prop="subtitle">
                    <el-input v-model="form.subtitle" placeholder="请输入副标题" max-length="200"></el-input>
                </el-form-item>
                <el-form-item label="品牌" prop="brand">
                    <el-input v-model="form.brand" placeholder="请输入品牌" max-length="50"></el-input>
                </el-form-item>
                <el-form-item label="商品分类" prop="categoryPath">
                    <el-cascader v-model="form.categoryPath" :options="categories" :props="cascaderProps"
                        @change="handleCategoryChange" placeholder="请选择商品分类" clearable></el-cascader>
                </el-form-item>

                <!-- 价格库存 -->
                <el-divider content-position="left">价格/库存</el-divider>
                <el-form-item label="销售价" prop="price">
                    <el-input-number v-model="form.price" :precision="2" :step="0.01" :min="0.01"
                        placeholder="请输入销售价"></el-input-number>
                </el-form-item>
                <el-form-item label="原价" prop="originalPrice">
                    <el-input-number v-model="form.originalPrice" :precision="2" :step="0.01" :min="form.price"
                        placeholder="请输入原价"></el-input-number>
                </el-form-item>
                <el-form-item label="库存" prop="stock">
                    <el-input-number v-model="form.stock" :min="0" :step="1" placeholder="请输入库存"></el-input-number>
                </el-form-item>

                <!-- 图片信息 -->
                <el-divider content-position="left">图片信息</el-divider>
                <!-- 主图上传 -->
                <el-form-item label="主图" prop="mainImage">
                    <!-- 主图上传组件：支持多图，横向排列 -->
                    <el-upload class="multi-main-image-uploader" 
                        :action="ossUploadHost"
                        :data="ossUploadData"
                        list-type="picture-card" 
                        :before-upload="beforeMainImageUpload" 
                        :on-success="handleMainImageSuccess" 
                        :on-error="handleUploadError" 
                        :on-preview="handleMainImagePreview" 
                        :on-remove="handleMainImageRemove" 
                        :on-exceed="handleMainUploadExceed"
                        :file-list="mainImageFileList" 
                         multiple 
                        :limit="1" 
                        >
                        <!-- 上传按钮 -->
                        <i class="el-icon-plus"></i>
                    </el-upload>
                    <div class="form-tip">支持 JPG/PNG 格式，每张不超过 2MB，最多上传 3 张</div>
                </el-form-item>

                <!-- 图片预览弹窗（与图片集共用，无需重复定义） -->
                <el-dialog v-model="dialogVisible">
                    <img width="100%" :src="dialogImageUrl" alt="主图预览" />
                </el-dialog>

                <!-- 图片集上传 -->
                <el-form-item label="图片集" prop="images">
                    <el-upload :action="ossUploadHost" :data="ossUploadData" list-type="picture-card"
                        :file-list="imageList" :on-preview="handlePictureCardPreview" :on-remove="handleRemove"
                        :before-upload="beforeImageUpload" :on-success="handleImageSuccess"
                        :on-error="handleUploadError" multiple :limit="5" :on-exceed="handleUploadExceed">
                    </el-upload>
                    <div class="form-tip">
                        支持 JPG/PNG 格式，每张不超过 2MB，最多上传 5 张
                    </div>

                    <!-- 图片预览弹窗 -->
                    <el-dialog v-model="dialogVisible">
                        <img width="100%" :src="dialogImageUrl" alt="预览图" />
                    </el-dialog>
                </el-form-item>

                <!-- 商品详情 -->
                <el-divider content-position="left">商品详情</el-divider>
                <el-form-item label="商品描述" prop="description">
                    <el-input type="textarea" :rows="4" placeholder="请输入商品描述（支持简单HTML）" v-model="form.description"
                        max-length="500"></el-input>
                    <div class="form-tip">最多输入500个字符，支持&lt;br&gt;&lt;p&gt;等标签</div>
                </el-form-item>

                <!-- 其他设置 -->
                <el-divider content-position="left">其他设置</el-divider>
                <el-form-item label="商品状态" prop="status">
                    <el-radio-group v-model="form.status">
                        <el-radio :label="1">上架</el-radio>
                        <el-radio :label="0">下架</el-radio>
                    </el-radio-group>
                </el-form-item>

                <!-- 提交按钮 -->
                <el-form-item>
                    <el-button type="primary" @click="submitForm" :loading="submitLoading">
                        {{ isEdit ? '保存修改' : '立即创建' }}
                    </el-button>
                    <el-button @click="goBack" style="margin-left: 10px;">返回列表</el-button>
                    <el-button type="text" @click="resetForm" style="margin-left: 10px;" :disabled="submitLoading">
                        重置表单
                    </el-button>
                </el-form-item>
            </el-form>
        </el-card>
    </div>
</template>

<script setup lang="ts">
// 1. 引入依赖
import { ref, reactive, onMounted, watch, computed, nextTick } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { ElMessage, ElForm, ElInput, ElInputNumber, ElCascader, ElDivider, ElRadioGroup, ElRadio, ElButton, ElUpload, ElCard, ElMessageBox } from 'element-plus'

// 2. 引入API
import { getProductDetail, saveProduct, getOssPolicy } from '../../api/productList.js'
import { getCategoryTree } from '../../api/categoryList.js'

// 3. 初始化核心数据
const router = useRouter()
const route = useRoute()

// 表单ref
const formRef = ref<InstanceType<typeof ElForm> | null>(null)
// 是否为编辑模式
const isEdit = ref(false)
// 提交加载状态
const submitLoading = ref(false)

// 图片相关状态
const imageList = ref<ImageItem[]>([])
const mainImageFileList = ref<ImageItem[]>([]); 
const dialogImageUrl = ref("")
const dialogVisible = ref(false)


// OSS上传相关
const ossUploadHost = ref("")
const ossUploadData = ref({})
const ossConfig = ref(null)

// 分类数据
const categories = ref([])

// 表单数据
const form = reactive({
    id: "",
    title: "",
    subtitle: "",
    brand: "",
    categoryId: "",
    categoryPath: [] as string[],
    mainImage: "",
    images: "",
    description: "",
    price: 0,
    originalPrice: 0,
    stock: 0,
    status: 1 as 0 | 1
})

// 级联选择器Props
const cascaderProps = computed(() => ({
    checkStrictly: false,
    value: 'id',
    label: 'name',
    children: 'children',
    emitPath: true,
    changeOnSelect: false
}));

// 4. 表单校验规则
const rules = ref({
    title: [
        { required: true, message: '请输入商品名称', trigger: 'blur' },
        { min: 2, max: 100, message: '商品名称长度需在2-100个字符之间', trigger: 'blur' }
    ],
    categoryPath: [
        { required: true, message: '请选择商品分类', trigger: 'change' },
    ],
    price: [
        { required: true, message: '请输入销售价', trigger: 'blur' },
        { type: 'number', min: 0.01, message: '销售价不能小于0.01元', trigger: 'blur' }
    ],
    originalPrice: [
        { required: true, message: '请输入原价', trigger: 'blur' },
        {
            validator: (rule: any, value: number, callback: (err?: Error) => void) => {
                if (value < form.price) {
                    callback(new Error('原价不能小于销售价'))
                } else {
                    callback()
                }
            },
            trigger: 'blur'
        }
    ],
    stock: [
        { required: true, message: '请输入库存', trigger: 'blur' },
        { type: 'number', min: 0, message: '库存不能为负数', trigger: 'blur' }
    ],
})

// 类型定义
interface ImageItem {
    url: string;
    name: string;
    uid: string;
}

// 5. 生命周期与数据加载
onMounted(async () => {
    await loadCategories()
    await getOssConfig() // 预先获取OSS配置

    watch(() => route.params.id, async (newId) => {
        isEdit.value = !!newId
        if (isEdit.value) {
            await loadProductData(newId as string)
        } else {
            resetForm(true)
        }
    }, { immediate: true })
});

/**
 * 加载商品分类树
 */
const loadCategories = async () => {
    submitLoading.value = true
    try {
        const res = await getCategoryTree()
        if (res.code === 0) {
            const cleanCategoryChildren = (list: any[]) => {
                if (!Array.isArray(list)) return;
                list.forEach(item => {
                    if (Array.isArray(item.children)) {
                        item.children.length === 0 ? delete item.children : cleanCategoryChildren(item.children);
                    }
                });
            };
            cleanCategoryChildren(res.data);
            categories.value = res.data;
        } else {
            ElMessage.error(res.msg || '获取商品分类失败');
        }
    } catch (err) {
        console.error('加载分类异常:', err);
        ElMessage.error('获取商品分类失败，请重试');
    } finally {
        submitLoading.value = false;
    }
};

/**
 * 获取OSS配置
 */
const getOssConfig = async () => {
    try {
        // 每次获取新的配置，避免策略过期
        const res = await getOssPolicy();
        if (res.code === 0 && res.data) {
            ossConfig.value = res.data;

            let host = res.data.host;
            if (!host.startsWith('https://') && !host.startsWith('http://')) {
                host = 'https://' + host;
            }
            ossUploadHost.value = host;

            ossUploadData.value = {
                key: '',
                OSSAccessKeyId: res.data.accessid,
                policy: res.data.policy,
                signature: res.data.signature,
                success_action_status: '200',
            };
            return true;
        } else {
            ElMessage.error(`获取上传配置失败：${res.msg || '未知错误'}`);
            return false;
        }
    } catch {
        ElMessage.error('获取上传配置失败，请重试');
        return false;
    }
};
/**
 * 检查OSS策略是否过期
 */
const isOssPolicyExpired = () => {
    if (!ossConfig.value || !ossConfig.value.expire)  return true;
    const expireTime = parseInt(ossConfig.value.expire) * 1000; // 转换为毫秒
    const currentTime = Date.now();
    const timeLeft = expireTime - currentTime;
    return timeLeft < 30000;
};

/**
 * 加载商品详情
 */
const loadProductData = async (id: string) => {
    submitLoading.value = true
    try {
        const res = await getProductDetail(id)
        if (res.code === 0) {
            const product = res.data;
            const categoryPath = product.categoryPath
                ? product.categoryPath.replace(/^,|,$/g, "").split(',').filter(Boolean)
                : [];
            Object.assign(form, {
                ...product,
                categoryPath,
                price: Number(product.price) || 0,
                originalPrice: Number(product.originalPrice) || 0,
                stock: Number(product.stock) || 0
            });

            // 处理图片集列表
            if (product.images) {               
                imageList.value = product.images.split(',')
                    .filter(url => url.trim()) 
                    .map(url => ({
                        url: url.trim(),
                        name: url.trim().substring(url.trim().lastIndexOf('/') + 1), // 提取文件名
                        uid: Date.now() + '-' + Math.random().toString(36).substr(2, 6) // 唯一ID（避免与主图冲突）
                    }));
            } else {
                imageList.value = []; // 无图片集时清空
            }
        } else {
            ElMessage.error(`获取商品信息失败：${res.msg}`);
            goBack();
        }
    } catch {
        ElMessage.error('获取商品信息失败，请重试');
        goBack();
    } finally {
        submitLoading.value = false;
    }
};

/**
 * 分类选择变更
 */
const handleCategoryChange = (value: string[]) => {
    if (value && value.length > 0) {
        form.categoryId = value[value.length - 1];
    }
};
/**
 * 主图上传超出数量限制（仅允许1张）
 */
const handleMainUploadExceed = () => {
    ElMessage.warning('主图仅支持上传1张，请先删除已上传图片');
};
/**
 * 主图上传前校验
 */
const beforeMainImageUpload = async (file: File) => {
    // 检查策略是否过期，如果过期则重新获取
    if (!ossConfig.value || isOssPolicyExpired()) {
        ElMessage.info('正在更新上传配置...');
        const configSuccess = await getOssConfig();
        if (!configSuccess) {
            ElMessage.error('OSS配置加载失败，无法上传');
            return false;
        }
    }

    const isImage = file.type.startsWith('image/');
    const isLt2M = file.size / 1024 / 1024 < 2;

    if (!isImage) {
        ElMessage.error('上传文件只能是图片格式（JPG/PNG）');
        return false;
    }
    if (!isLt2M) {
        ElMessage.error('上传图片大小不能超过 2MB');
        return false;
    }

    // 设置文件名和路径
    const suffix = file.name.substring(file.name.lastIndexOf('.'));
    const filename = `${Date.now()}_${Math.random().toString(36).substr(2, 6)}${suffix}`;
    const fullPath = `${ossConfig.value.dir}${filename}`;

    ossUploadData.value = {
        ...ossUploadData.value,
        key: fullPath
    };

    console.log('上传配置:', {
        host: ossUploadHost.value,
        key: fullPath,
        policy: ossUploadData.value.policy.substring(0, 50) + '...' // 只显示部分
    });

    return true;
};

/**
 * 图片集上传前校验
 */
const beforeImageUpload = async (file: File) => {
    const isImage = file.type.startsWith('image/');
    const isLt2M = file.size / 1024 / 1024 < 2;

    if (!isImage) {
        ElMessage.error('只能上传图片格式（JPG/PNG）');
        return false;
    }
    if (!isLt2M) {
        ElMessage.error('图片大小不能超过 2MB');
        return false;
    }

    // 设置文件名和路径
    const suffix = file.name.substring(file.name.lastIndexOf('.'));
    const filename = `${Date.now()}_${Math.random().toString(36).substr(2, 6)}${suffix}`;
    const fullPath = `${ossConfig.value.dir}${filename}`;

    ossUploadData.value = {
        ...ossUploadData.value,
        key: fullPath
    };

    return true;
};

/**
 * 主图上传成功回调
 */
const handleMainImageSuccess = (response: any, file: any) => {
    const fileUrl = `${ossConfig.value.host}/${ossUploadData.value.key}`;
    form.mainImage = fileUrl;
    // 同步主图文件列表（仅保留当前主图）
    mainImageFileList.value = [{ url: fileUrl, name: file.name, uid: file.uid }];
    // 重置OSS上传key，避免重复
    ossUploadData.value.key = '';
    ElMessage.success('主图上传成功');
};

/**
 * 图片集上传成功回调 - 修复路径处理
 */
const handleImageSuccess = (response: any, file: any, fileList: any[]) => {
    const fileUrl = `${ossConfig.value.host}/${ossUploadData.value.key}`;

    // 更新图片列表
    const newImage = {
        url: fileUrl,
        name: file.name,
        uid: file.uid
    };

    // 检查是否已存在
    const exists = imageList.value.some(img => img.url === fileUrl);
    if (!exists) {
        imageList.value.push(newImage);
    }

    // 更新表单中的图片集字符串
    form.images = imageList.value.map(img => img.url).join(',');
    ElMessage.success('图片上传成功');
};

/**
 * 上传错误处理
 */
const handleUploadError = (error: Error) => {
    console.error('上传失败:', error);
    ElMessage.error('图片上传失败，请重试');
};

/**
 * 图片预览
 */
const handlePictureCardPreview = (file) => {
    dialogImageUrl.value = file.url;
    dialogVisible.value = true;
};

/**
 * 主图预览
 */
const handleMainImagePreview = () => {
    if (form.mainImage) {
        dialogImageUrl.value = form.mainImage;
        dialogVisible.value = true;
    }
};

/**
 * 移除图片集中的图片
 */
const handleRemove = (file: ImageItem, fileList: ImageItem[]) => {
    imageList.value = fileList;
    form.images = fileList.map(item => item.url).join(',');
};

/**
 * 删除主图
 */
const handleMainImageRemove = () => {
    form.mainImage = "";
    mainImageFileList.value = []; // 清空主图文件列表
    ElMessage.info('已移除主图');
};

/**
 * 图片上传数量超限
 */
const handleUploadExceed = () => {
    ElMessage.warning('最多只能上传5张图片');
};

/**
 * 提交表单
 */
const submitForm = async () => {
    if (!formRef.value) return;

    try {
        await formRef.value.validate();
    } catch {
        ElMessage.warning('请完善表单必填项');
        return;
    }

    // 确保分类路径格式正确
    const submitData = {
        ...form,
        categoryPath: form.categoryPath.length > 0 ? `,${form.categoryPath.join(',')},` : '',
        price: Number(form.price),
        originalPrice: Number(form.originalPrice),
        stock: Number(form.stock)
    };

    submitLoading.value = true;
    try {
        const res = await saveProduct(submitData);
        if (res.code === 0) {
            ElMessage.success(isEdit.value ? '商品修改成功' : '商品上架成功');
            goBack();
        } else {
            ElMessage.error(`${isEdit.value ? '商品修改' : '商品上架'}失败：${res.msg}`);
        }
    } catch (err) {
        console.error('保存商品异常:', err);
        ElMessage.error(`${isEdit.value ? '商品修改' : '商品上架'}失败，请重试`);
    } finally {
        submitLoading.value = false;
    }
};

/**
 * 重置表单
 */
const resetForm = (force = false) => {
    if (!formRef.value) return;

    if (isEdit.value && !force) {
        ElMessageBox.confirm(
            '重置表单将清除当前编辑内容，是否继续？',
            '确认重置',
            {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'info'
            }
        ).then(async () => {
            await doReset();
        }).catch(() => { });
    } else {
        doReset();
    }
};

const doReset = async () => {
    formRef.value?.resetFields();
    form.mainImage = "";
    form.images = "";
    imageList.value = [];
    form.categoryPath = [];
    form.categoryId = "";

    if (isEdit.value && route.params.id) {
        await loadProductData(route.params.id as string);
    } else {
        form.status = 1;
    }
};

/**
 * 返回商品列表页
 */
const goBack = () => {
    router.push('/product/list');
};
</script>

<style scoped>
.product-edit {
    padding: 20px;
}

.box-card {
    height: 100%;
}

.avatar-uploader {
    width: 150px;
    height: 150px;
}

.avatar {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.avatar-wrapper {
    position: relative;
    width: 100%;
    height: 100%;
    border-radius: 4px;
    overflow: hidden;
    border: 1px solid #eee;
}

.avatar-actions {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    background: rgba(0, 0, 0, 0.5);
    color: #fff;
    display: flex;
    justify-content: center;
    padding: 5px 0;
    opacity: 0;
    transition: opacity 0.3s;
}

.avatar-wrapper:hover .avatar-actions {
    opacity: 1;
}

.avatar-actions span {
    margin: 0 10px;
    cursor: pointer;
}

.form-tip {
    margin-top: 6px;
    font-size: 12px;
    color: #999;
}
</style>